<?php

namespace App\Models;

use App\Cost\Price;
use App\Enums\OrderItemType;
use App\Enums\OrderLogAction;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class OrderItem extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'order_id', 'goods_id', 'count', 'money', 'discount_money', 'origin_money',
        'type', 'cost_rule_id', 'start_at', 'end_at',
        'table_id', 'assistant_user_id', 'specification', 'is_virtual',
        'is_free', 'pause_at', 'pause_minutes',
    ];

    protected $casts = [
        'start_at' => 'datetime',
        'end_at' => 'datetime',
        'type' => OrderItemType::class,
        'is_virtual' => 'boolean',
        'is_free' => 'boolean',
    ];

    protected function serializeDate(\DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }

    public function order()
    {
        return $this->belongsTo(Order::class);
    }

    public function goods()
    {
        return $this->belongsTo(Goods::class);
    }

    public function table()
    {
        return $this->belongsTo(Table::class);
    }

    public function costRule()
    {
        return $this->belongsTo(CostRule::class);
    }

    public function assistantUser()
    {
        return $this->belongsTo(User::class, 'assistant_user_id');
    }

    public function getTotalMinutes($finishDate)
    {
        $startAt = Carbon::parse($this->start_at);
        $endAt = Carbon::parse($finishDate);

        $pauseMinutes = $this->pause_minutes;
        if (!empty($this->pause_at)) {
            $pauseAt = Carbon::parse($this->pause_at);
            $pauseMinutes += $endAt->diffInMinutes($pauseAt);
        }

        return $endAt->diffInMinutes($startAt) - $pauseMinutes;
    }

    /**
     * @param $finishDate
     * @return Price
     */
    public function getPrice($finishDate)
    {
        if (empty($this?->costRule))
            return new Price();

        $pauseMinutes = $this->pause_minutes;
        if (!empty($this->pause_at)) {
            $pauseAt = Carbon::parse($this->pause_at);
            $pauseMinutes += Carbon::parse($finishDate)->diffInMinutes($pauseAt);
        }

        $finishDate = Carbon::parse($finishDate)->subMinutes($pauseMinutes)->format('Y-m-d H:i:s');

        $costRule = $this->costRule->data;
        return $costRule->getPrice($this->start_at, $finishDate);
    }

    /**
     * @param $finishDate
     * @return float|int
     */
    public function getTotalMoney($finishDate)
    {
        if (!empty($this->end_at))
            return $this->money;

        $price = $this->getPrice($finishDate);

        return ($price->basePrice + $price->timeOutPrice) / 100;
    }

    /**
     * 暂停
     * @return $this
     */
    public function pause()
    {
        OrderLog::create([
            'order_id' => $this->order_id,
            'order_item_id' => $this->id,
            'user_id' => auth()->id(),
            'action' => $this->type == OrderItemType::Table ? OrderLogAction::StopTableTiming : OrderLogAction::StopAssistantTiming,
        ]);

        // 暂停只针对桌位和助教
        if (!in_array($this->type, [OrderItemType::Table, OrderItemType::Assistant]))
            return $this;

        if (!empty($this->pause_at))
            return $this;

        $this->pause_at = now();
        $this->save();

        return $this;
    }

    /**
     * 取消暂停
     * @return $this
     */
    public function unpause()
    {
        if (empty($this->pause_at))
            return $this;

        $pauseAt = Carbon::parse($this->pause_at);
        $pauseMinutes = $this->pause_minutes + $pauseAt->diffInMinutes(now());

        $this->pause_at = null;
        $this->pause_minutes = $pauseMinutes;
        $this->save();

        return $this;
    }
}
